package app.objectstoragedemo.controller;

import app.objectstoragedemo.Pojo.Mapper.FileStorage;
import app.objectstoragedemo.Pojo.Result;
import app.objectstoragedemo.Pojo.Vo.FileLimitVo;
import app.objectstoragedemo.Pojo.Vo.UploadFileVo;
import app.objectstoragedemo.service.impl.FileServiceInterface;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;


@RestController
@Slf4j
@RequiredArgsConstructor
public class ObjectStorageController {

    public final FileServiceInterface fileService;

    //获取文件列表
    @RequestMapping("/getList")
    public Result<?> getList(@RequestParam(required = false, defaultValue = "1") int Current, @RequestParam(required = false, defaultValue = "10") int limit) {
        //查询数据库
        FileLimitVo fileLimitVo = fileService.InquireFile(Current, limit);

        return Result.success(fileLimitVo);
    }

    //上传文件
    @RequestMapping("/add")
    public Result<?> uploadFile(@NotNull(message = "请选择进行删除") @RequestParam("file") MultipartFile file) {
        //添加到数据库
        UploadFileVo uploadFileVo = fileService.uploadFile(file);

        return Result.success(uploadFileVo);
    }

    //下载文件
    @RequestMapping("/download/{uuid}")
    public void downloadFile(@PathVariable String uuid, HttpServletResponse response) {
        FileStorage fileStorage = fileService.selectByUuid(uuid);
        Path imageLocation = Path.of(fileStorage.getPath());
        String fileName = fileStorage.getName();
        try {
            byte[] fileBytes = Files.readAllBytes(imageLocation);
            response.reset(); // 清除之前的响应头和内容
            // 设置响应头
            response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, StandardCharsets.UTF_8) + "\";");
            // 字符编码 utf-8
            response.setCharacterEncoding("utf-8");
            // 设置响应类型
            response.setContentType("application/octet-stream");
            // 设置响应内容长度
            response.setContentLength(fileBytes.length);
            // 输出响应内容
            response.getOutputStream().write(fileBytes);
            // 刷新缓冲区
            response.getOutputStream().flush();
        } catch (Exception e) {
            throw new RuntimeException("尝试提供文件时出错", e);
        }
    }

    //浏览器支持打开什么类型的文件
    // 文本文件：浏览器可以打开和显示纯文本文件，包括 TXT、CSV 等。
    // 图片文件：浏览器可以显示常见的图片格式，包括 JPEG、PNG、GIF 等。
    // HTML 文件：浏览器可以解析和显示 HTML 文件，包括 HTML、XHTML 等。
    // PDF 文件：浏览器通常内置了 PDF 阅读器，可以直接打开和查看 PDF 文件。
    @RequestMapping("/show/{uuid}")
    public void showFile(@PathVariable String uuid, HttpServletResponse response) {
        // 读取文件
        FileStorage fileStorage = fileService.selectByUuid(uuid);
        // 获取文件路径
        Path imageLocation = Path.of(fileStorage.getPath());
        try {
            // 修改为你的图片路径
            byte[] imageBytes = Files.readAllBytes(imageLocation);

            // 设置响应类型
            response.setContentType(fileStorage.getType()); // 根据实际图片类型设置MIME类型
            // 设置响应内容长度
            response.setContentLength(imageBytes.length);
            // 输出响应内容
            response.getOutputStream().write(imageBytes);
            // 刷新缓冲区
            response.getOutputStream().flush();
        } catch (Exception e) {
            throw new RuntimeException("尝试提供文件时出错", e);
        }
    }

    //删除文件
    @RequestMapping("/delete/{file}")
    public Result<?> deleteFile(@PathVariable String file) {
        //删除数据库中的记录
        int i = fileService.deleteFile(file);
        if (i == 0) {
            return Result.failure("文件不存在");
        }
        //删除文件
        return Result.success("文件删除成功");
    }

}
